package com.traveldream.frontend.managed_beans;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Vector;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.traveldream.entities.Booking;
import com.traveldream.entities.BookingPK;
import com.traveldream.entities.CustomPacket;
import com.traveldream.entities.DefaultPacket;
import com.traveldream.entities.Excursion;
import com.traveldream.entities.Flight;
import com.traveldream.entities.Hotel;
import com.traveldream.entities.Invite;
import com.traveldream.entities.InvitePK;
import com.traveldream.entities.Packet;
import com.traveldream.entities.Place;
import com.traveldream.entities.Product;
import com.traveldream.entities.User;
import com.traveldream.entity_managers.BookingManager;
import com.traveldream.entity_managers.CustomerManager;
import com.traveldream.entity_managers.InviteManager;
import com.traveldream.entity_managers.PacketManager;
import com.traveldream.entity_managers.PlaceManager;
import com.traveldream.entity_managers.ProductManager;


/**
 *	packet controller managed bean
 *		- actions for creating / editing packets
 *		- methods and attributes for creating/editing packet fields 
 */

@ManagedBean(name="packetFrontend")
@SessionScoped
public class PacketBean {
	

	// call all instances of entity managers via @EJB injection
	@EJB
	private ProductManager prM; // instance of product manager
	
	@EJB
	private PacketManager pm; // instance of packet manager

	@EJB
	private CustomerManager cm; // instance of packet manager
	
	@EJB
	private InviteManager im; // instance of packet manager
	
	@EJB
	private BookingManager bm; // instance of booking manager
	
	@EJB
	private PlaceManager plM; // instance of booking manager
	
	// some attributes
	private List list;  // packet list
	private Packet current; 	// current packet
	private CustomPacket customPacket;
	private Booking booking;
	private List<Invite> inviteList;
	
	private Excursion excursion;
	private Hotel hotel;
	private Flight flight;
	
	private String placeId;
	private Date startingDate;
	private Date endingDate;
	private String friendEmail;
	
	/**
	 * constructor & initialization
	 */
	public PacketBean()
	{
		current = new Packet();
		current.setPlace(new Place());
		
		customPacket = null;
		booking = new Booking();
		
		list = new ArrayList<DefaultPacket>();
		inviteList = new ArrayList<Invite>();
		
		placeId = "";
		friendEmail = "";
		startingDate = new Date();
		Calendar cal = Calendar.getInstance();  
		cal.setTime(startingDate);  
		cal.add(Calendar.MONTH,1);  
		endingDate = cal.getTime();  
	
		
		excursion = null;
		hotel = null;
		flight = null;
	}
	
	// actions
	
	// search packet action
	public String searchAction(){
		// finds packet filtering db table by dates and place selected by customer
		this.list = pm.findByDatesAndPlace(startingDate,endingDate,plM.find(placeId));
		
		// reset field values
		placeId = "";
		startingDate = new Date();
		Calendar cal = Calendar.getInstance();  
		cal.setTime(startingDate);  
		cal.add(Calendar.MONTH,1);  
		endingDate = cal.getTime();  
		
		return "/frontend/search/results";
	}
	
	/** 
	 * select packet action
	 * @param String id
	 * @return String
	 */
	public String selectAction(String id){
		// parse parameter
		int packetId = Integer.parseInt(id);
		// load in this.current selected packet
		this.current = pm.findDefaultPacket(packetId).getPacket();
		return "/frontend/booking/firstConfirm";
	}
	
	
	/**
	 *  customize packet action
	 * @return String
	 */
	public String customizeAction(){
		// just call the VIEW layer
		return "/frontend/package/edit";
	}
	
	/** 
	 * create custom packet action --> end of packet customization process
	 * @return String
	 */
	public String createCustomPacketAction(){
		Packet packet = new Packet();
		
		// copy dates and place
		packet.setStartingDate(current.getStartingDate());
		packet.setEndingDate(current.getEndingDate());
		packet.setPlace(current.getPlace());
		
		// initialize product list
		List<Product> productList = new ArrayList<Product>();
		
		// if user selected a flight, add it to list
		if(this.flight!=null)
		{
			productList.add(flight.getProduct());
			flight=null;
		}

		// if user selected an hotel, add it to list
		if(this.hotel!=null)
		{
			productList.add(hotel.getProduct());
			this.hotel=null;
		}

		// if user selected an excursion, add it to list
		if(this.excursion!=null)
		{
			System.out.print("Choosed excursion:"+excursion.getName());
			productList.add(excursion.getProduct());
			this.excursion = null;
		}	
		
		// product list size cannot be 0!!!
		if(productList.size()==0)
		{
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("E' necessario scegliere almeno un prodotto!"));
			return "/frontend/package/edit";
		}
		
		
		// set products to packet product list
		packet.setProducts(productList);
		current = packet;
		
		// create custom packet and link it to created packet
		this.customPacket = new CustomPacket();
		customPacket.setPacket(current);
		customPacket.setUser(cm.getAuthenticatedUser());
		
		
		return "/frontend/booking/secondConfirm";
	}
	
	/**
	 *  book packet action
	 * @return String
	 */
	public String bookAction(){
		


		User currentUser = cm.getAuthenticatedUser();
		BookingPK bookingPK = new BookingPK();

		bookingPK.setCustomerEmail(currentUser.getEmail());
		
		
		// if customer has customized a packet
		if(customPacket==null)
		{
			bookingPK.setPacketId(current.getId());
			booking.setPacket(current);
		}
		// otherwise if he selected a default packet
		else
		{
			booking.setPacket(customPacket.getPacket());
			pm.create(customPacket);
			bookingPK.setPacketId(customPacket.getPacket().getId());
		}

		if(bm.find(bookingPK) != null)
		{
			return "/frontend/booking/error";
		}
		
		booking.setId(bookingPK);
		booking.setDate(new Date());
		booking.setUser(currentUser);
		bm.create(booking);

		// reset invite list
		this.inviteList = new ArrayList<Invite>();
		
		return "/frontend/booking/summary";
	}
	
	/**
	 *  invite friend to booking
	 * @return String
	 */
	public String inviteFriend(){
		InvitePK invitePK = new InvitePK();
		invitePK.setBookedPacketId(this.current.getId());
		invitePK.setCustomerBookedEmail(cm.getAuthenticatedUser().getEmail());
		
		Invite invite = new Invite();
		invite.setBooking(this.booking);
		invite.setDate(new Date());
		invite.setReceivingEmail(this.friendEmail);
		invite.setId(invitePK);
		
		im.create(invite); // save invite in DB
		this.inviteList.add(invite); //add it to invite list
		
		invite.sendEmail(); // send email
		
		
		// reset email
		friendEmail = "";

		return "";
	}
	
	
	
	// getters and setters
	
	
	/**
	 * query the DB searching flights compatible with
	 * user choices on dates and place
	 * @return
	 */
	public List<Flight> getFlightList(){
		List<Flight> list = prM.findFlightByDatesAndPlace(current.getStartingDate(),current.getEndingDate(),current.getPlace());
		return list;
	}
	/**
	 * query the DB searching hotels compatible with
	 * user choices on dates and place
	 * @return
	 */
	public List<Hotel> getHotelList(){
		List<Hotel> list = prM.findHotelByDatesAndPlace(current.getStartingDate(),current.getEndingDate(),current.getPlace());
		return list;
	}

	/**
	 * query the DB searching excursions compatible with
	 * user choices on dates and place
	 * @return
	 */
	public List<Excursion> getExcursionList(){
		//List<Excursion> list = prM.findAllExcursions();
		List<Excursion> list = prM.findExcursionByDatesAndPlace(current.getStartingDate(),current.getEndingDate(),current.getPlace());
		return list;
	}
	
	public Packet getCurrent(){
		return this.current;
	}
	public void setCurrent(Packet current){
		this.current = current;
	}

	public CustomPacket getCustomPacket(){
		return this.customPacket;
	}
	public void setCustomPacket(CustomPacket customPacket)	{
		this.customPacket = customPacket;
	}
	
	public List getList() {
		return list;
	}

	public void setList(List list) {
		this.list = list;
	}

	public Date getEndingDate() {
		return endingDate;
	}

	public void setEndingDate(Date endingDate) {
		this.endingDate = endingDate;
	}

	public Date getStartingDate() {
		return startingDate;
	}

	public void setStartingDate(Date startingDate) {
		this.startingDate = startingDate;
	}

	public String getPlaceId() {
		return placeId;
	}

	public void setPlaceId(String placeId) {
		this.placeId = placeId;
	}

	public Excursion getExcursion() {
		return excursion;
	}

	public void setExcursion(Excursion excursion) {
		this.excursion = excursion;
	}

	public Hotel getHotel() {
		return hotel;
	}

	public void setHotel(Hotel hotel) {
		this.hotel = hotel;
	}

	public Flight getFlight() {
		return flight;
	}

	public void setFlight(Flight flight) {
		this.flight = flight;
	}

	public String getFriendEmail() {
		return friendEmail;
	}

	public void setFriendEmail(String friendEmail) {
		this.friendEmail = friendEmail;
	}

	public List<Invite> getInviteList() {
		return inviteList;
	}

	public void setInviteList(List<Invite> inviteList) {
		this.inviteList = inviteList;
	}
	
	
	
}
